﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.DirectoryServices;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Wordprocessing;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;
using MT.Enterprise.Utils.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NP.BPMReportPlatform.BuyerScarletInformation.Dto;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.EmailHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Business.SWSendMail;
using NP.BPMReportPlatform.Entities.BPM_Engine;
using NP.BPMReportPlatform.HandInvoice.Dto;
using NP.BPMReportPlatform.SF.Dto;
using NP.Enterprise.Utils.HanaOdbc;
using NP.Enterprise.Utils.Http;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using RazorEngine;
using RazorEngine.Templating;
using RestSharp;
using SqlSugar;

namespace NP.BPMReportPlatform.RecurringJobs
{
    public class RedRushJob : BpmReportPlatformRecurringJob, IRedRushJob
    {
        private readonly SqlSugarClient _db, _dbEngine;

        // private readonly ILogger<BuyerScarletInformationService> _logger;
        private readonly INPRestHttpHelper _httpClient;

        private readonly string _esbUrl;
        private readonly string _esbInvoiceUrl;
        private readonly IHanaOdbcAppService _hanaAppService;
        private readonly string _FINANCEAPIURL;
        private readonly string _SHOUGONGFAPIAOCOMPANY;
        private readonly string _esbFinanceHeaderApi;
        private readonly string _esbFinanceTokenApi;
        private readonly string _pytUrl;
        private readonly IEmailAPPService _emailAPPService;
        private readonly ICapPublisher _capBus;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarAppService"></param>
        /// <param name="httpClient"></param>
        /// <param name="configuration"></param>
        public RedRushJob(ISqlSugarAppService sqlSugarAppService, INPRestHttpHelper httpClient,
            IConfiguration configuration, IHanaOdbcAppService hanaAppService, IEmailAPPService emailAPPService, ICapPublisher capBus)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _httpClient = httpClient;
            _esbUrl = configuration["Nippon:ESB:ESBCommApi"];
            _esbInvoiceUrl = configuration["Nippon:ESB:ESBInvoiceApi"];
            _hanaAppService = hanaAppService;
            _FINANCEAPIURL = configuration["RedRush:FINANCEAPIURL"];
            _SHOUGONGFAPIAOCOMPANY = configuration["RedRush:SHOUGONGFAPIAOCOMPANY"];
            _esbFinanceHeaderApi = configuration["RedRush:ESBFinanceHeadersApi"];
            _esbFinanceTokenApi = configuration["RedRush:ESBFinanceTokenApi"];
            _pytUrl = configuration["RedRush:ESBCommNewApi"];
            _emailAPPService = emailAPPService;
            _capBus = capBus;
        }

        public async Task GetSAPVoucher()
        {
            try
            {
                List<RedRushManualInvoice> upodateInvoices = new List<RedRushManualInvoice>();
                List<RedRushManualInvoiceCostCenter> upodateCostCenter = new List<RedRushManualInvoiceCostCenter>();
                List<HandInvoiceJob> invoiceJobs = new List<HandInvoiceJob>();
                var handInvoices = await _db.Queryable<HandInvoiceJob>()
                                    .Where(t => t.Status == 0 && t.Type == "1" && t.Count <= 10)
                                    .OrderBy(t => t.Count, OrderByType.Asc)
                                    .Take(100).ToListAsync();
                if (handInvoices.Count == 0)
                {
                    return;
                }

                string instanceNumbers = string.Empty;
                List<string> instanceIds = new List<string>();
                handInvoices.ForEach(x =>
                {
                    instanceIds.Add(x.InstanceNumber);
                    instanceNumbers = instanceNumbers + "'" + x.InstanceNumber.PadLeft(18, '0') + "',";
                });
                instanceNumbers = instanceNumbers.TrimEnd(',');

                // 查询RedRushManualInvoice表
                var redRushManualInvoices = await _db.Queryable<RedRushManualInvoice>()
                                            .Where(t => instanceIds.Contains(t.InstanceNumber)).ToListAsync();

                // 查询RedRushManualInvoice表
                var costCenters = await _db.Queryable<RedRushManualInvoiceCostCenter>()
                                            .Where(t => instanceIds.Contains(t.InstanceNumber)).ToListAsync();
                // 查询hana数据库
                var sql = $@"SELECT BELNR1 ,BELNR2 ,ORIGININVOICEN ,ORIGININVOICECODE ,ZKEY_BPM ,XUHAO ,KPRQ ,KPSJ,FPDMBTR  FROM erp.ZFIT053 
                        WHERE ZKEY_BPM IN ({instanceNumbers})";
                var rst = (await _hanaAppService.GetListAsync<HanaDto.ZFIT053Dto>(sql)).ToList();

                handInvoices.ForEach(x =>
                {
                    var voucher = rst.Where(t => t.ZKEY_BPM == x.InstanceNumber.PadLeft(18, '0') && t.XUHAO == x.RedRushManualInvoice_Order.PadLeft(3, '0')).OrderByDescending(t => t.FPDMBTR).FirstOrDefault();
                    if (voucher != null)
                    {
                        if (x.CustomCode.StartsWith("13") || x.CustomCode.StartsWith("013"))
                        {
                            var item = redRushManualInvoices.Where(t => t.InstanceNumber == x.InstanceNumber && t.Order == x.RedRushManualInvoice_Order).FirstOrDefault();
                            //开票方和收票方凭证都存在或者收票方公司代码为0存在开票方凭证和发票号码
                            if ((!string.IsNullOrWhiteSpace(voucher.BELNR1) && !string.IsNullOrWhiteSpace(voucher.BELNR2))
                            || (!string.IsNullOrWhiteSpace(voucher.BELNR1) && !string.IsNullOrWhiteSpace(voucher.ORIGININVOICEN) && item.ReceiverCompanyCode == "0"))
                            {
                                
                                if (item != null)
                                {
                                    item.CertificateNo = voucher.BELNR1;
                                    item.RecipientCertificateNo = voucher.BELNR2;
                                    item.InvoiceNo = voucher.ORIGININVOICEN;
                                    item.InvoiceCode = voucher.ORIGININVOICECODE;
                                    item.InvoiceDate = DateTime.Parse(DateTime.ParseExact(voucher.KPRQ, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture).ToString("yyyy-MM-dd"));
                                    upodateInvoices.Add(item);
                                    var result = Request(item.Id, item.Order, voucher.KPRQ, voucher.ORIGININVOICEN);
                                    x.Count = x.Count + 1;
                                    x.Status = 1;
                                    x.RequestResult = Newtonsoft.Json.JsonConvert.SerializeObject(result);
                                }
                            }
                            else
                            {
                                x.Count = x.Count + 1;
                            }
                        }
                        else
                        {
                            if (!string.IsNullOrWhiteSpace(voucher.BELNR1))
                            {
                                var item = redRushManualInvoices.Where(t => t.InstanceNumber == x.InstanceNumber && t.Order == x.RedRushManualInvoice_Order).FirstOrDefault();
                                if (item != null)
                                {
                                    item.CertificateNo = voucher.BELNR1;
                                    item.InvoiceNo = voucher.ORIGININVOICEN;
                                    item.InvoiceCode = voucher.ORIGININVOICECODE;
                                    upodateInvoices.Add(item);
                                    var result = Request(item.Id, item.Order, voucher.KPRQ, voucher.ORIGININVOICEN);
                                    x.Count = x.Count + 1;
                                    x.Status = 1;
                                    x.RequestResult = Newtonsoft.Json.JsonConvert.SerializeObject(result);
                                }
                            }
                            else
                            {
                                x.Count = x.Count + 1;
                            }
                        }
                    }
                    invoiceJobs.Add(x);
                });

                // 单独更新成本账的凭证
                //handInvoices.ForEach(x =>
                //{
                //    var costCenter = costCenters.Where(t => t.InstanceNumber == x.InstanceNumber).ToList();
                //    if (costCenter != null && costCenter.Count > 0)
                //    {
                //        costCenter.ForEach(x =>
                //        {
                            
                //        });
                //    }
                //});

                if (upodateInvoices != null)
                {
                    _db.Updateable(upodateInvoices)
                        .UpdateColumns(t => new { t.CertificateNo, t.RecipientCertificateNo, t.InvoiceNo, t.InvoiceCode })
                        .ExecuteCommand();
                    _db.Updateable(invoiceJobs).UpdateColumns(t => new { t.Count, t.Status, t.RequestResult }).ExecuteCommand();
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        public async Task PostInvoiceUrlEmail()
        {
            List<HandInvoiceJob> invoiceJobs = new List<HandInvoiceJob>();
            var handInvoices = await _db.Queryable<HandInvoiceJob>()
                                .Where(t => t.Status == 0 && t.Type == "2")
                                .OrderBy(t => t.Count, OrderByType.Asc)
                                .Take(100).ToListAsync();
            if (handInvoices.Count == 0)
            {
                return;
            }
            handInvoices.ForEach( x =>
            {
                var invoiceNoIsNull =  _db.Queryable<RedRushManualInvoice>().Where(t => t.InstanceNumber == x.InstanceNumber && string.IsNullOrWhiteSpace(t.InvoiceNo)).Any();
                if (!invoiceNoIsNull)
                {
                    var invocies = _db.Queryable<RedRushManualInvoice>().Where(t => t.InstanceNumber == x.InstanceNumber).ToList();
                    var pytResult =   _searchTicketFromESB(invocies.Select(x => x.InvoiceNo).ToList().JoinAsString(",")).Result;
                    if (pytResult != null && pytResult.code == "1" && pytResult.message == "成功")
                    {
                        if (pytResult.result.data.Any())
                        {
                            List<SWSendMailSelected> list = new List<SWSendMailSelected>();
                            list = pytResult.result.data.Select(t => new SWSendMailSelected()
                            {
                                electricInvoiceCode = t.invoiceNo,
                                amountWithTax = t.amountWithTax,
                                invoiceDate = t.dateIssued,
                                taxRate = t.taxRate,
                                tax = t.taxAmount,
                                sellerCode = t.sellerTaxNo,
                                sellerName = t.sellerName,
                                sellerCompanyCode = t.sellerNo,
                                buyerCode = t.buyerTaxNo,
                                buyerName = t.buyerName,
                                buyerCompanyCode = t.buyerNo,
                                XMLURL = t.xmlUrl,
                                OFDURL = t.ofdUrl,
                                PDFURL = t.pdfUrl
                            }).ToList();
                            if (list.Count > 0)
                            {
                                SendMail1(x.InstanceNumber, list);
                                x.Count = x.Count + 1;
                                x.Status = 1;
                                x.RequestResult = Newtonsoft.Json.JsonConvert.SerializeObject(list);
                                invoiceJobs.Add(x);
                            }
                            else
                            {
                                x.Count = x.Count + 1;
                                x.Status = 1;
                                x.RequestResult = "list=null;" + Newtonsoft.Json.JsonConvert.SerializeObject(pytResult);
                                invoiceJobs.Add(x);
                            }
                        }
                        else
                        {
                            x.Count = x.Count + 1;
                            x.Status = 1;
                            x.RequestResult = "data=null;" + Newtonsoft.Json.JsonConvert.SerializeObject(pytResult);
                            invoiceJobs.Add(x);
                        }
                    }
                    else
                    {
                        x.Count = x.Count + 1;
                        x.Status = 1;
                        x.RequestResult = "pytResult=null;" + Newtonsoft.Json.JsonConvert.SerializeObject(pytResult);
                        invoiceJobs.Add(x);
                    }
                }
            });
            if (invoiceJobs != null && invoiceJobs.Count > 0)
            {
                _db.Updateable(invoiceJobs).UpdateColumns(t => new { t.Count, t.Status, t.RequestResult }).ExecuteCommand();
            }
        }

        public async Task ThirdCallback()
        {
            List<HandInvoiceJob> invoiceJobs = new List<HandInvoiceJob>();
            var handInvoices = await _db.Queryable<HandInvoiceJob>()
                                .Where(t => t.Status == 0 && t.Type == "3")
                                .OrderBy(t => t.Count, OrderByType.Asc)
                                .Take(100).ToListAsync();
            if (handInvoices.Count == 0)
            {
                return;
            }
            handInvoices.ForEach(x =>
            {
                var invoiceNoIsNull = _db.Queryable<RedRushManualInvoice>().Where(t => t.InstanceNumber == x.InstanceNumber && string.IsNullOrWhiteSpace(t.InvoiceNo)).Any();
                if (!invoiceNoIsNull)
                {
                    var invocies = _db.Queryable<RedRushManualInvoice>().Where(t => t.InstanceNumber == x.InstanceNumber).ToList();
                    CallBackDto callBackDto = new CallBackDto();
                    callBackDto.orderId = x.RedRushManualInvoice_Id;
                    List<Invoices> invoices = new List<Invoices>();
                    invocies.ForEach(t => {
                        invoices.Add(new Invoices {
                            rowId = t.Order,
                            invoiceState = "1",
                            invoiceNo = t.InvoiceNo,
                            CertificateNo = t.CertificateNo,
                            RecipientCertificateNo = t.RecipientCertificateNo,
                            remark = "",
                            invoiceDate = t.InvoiceDate.ToString()
                        });
                    });
                    callBackDto.details = invoices;
                    var callBackResult = ThirdCallbackPostESB(callBackDto).Result;
                    x.Count = x.Count + 1;
                    x.RequestResult = Newtonsoft.Json.JsonConvert.SerializeObject(callBackResult);
                    if (callBackResult.Code == "0")
                    {
                        x.Status = 1;
                    }
                    
                    invoiceJobs.Add(x);
                }
            });
            if (invoiceJobs != null && invoiceJobs.Count > 0)
            {
                _db.Updateable(invoiceJobs).UpdateColumns(t => new { t.Count, t.Status, t.RequestResult }).ExecuteCommand();
            }
        }

        public async Task<CallBackResult> ThirdCallbackPostESB(CallBackDto callBackDto)
        {
            var headers = new Dictionary<string, string>
            {
                {"sourceSystem", "BPM"},
                {"serviceName", "S_XXX_Finance_ManualInvoiceCallBack_S"},
            };
            
            var rst = await _httpClient.ESBPostAsync<CallBackResult>(_esbUrl, callBackDto, headers);
            return rst;
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        private void SendMail1(string instanceNumber, List<SWSendMailSelected> list)
        {
            string email = "YANGJUNSZ@NIPPONPAINT.COM.CN";
            var toEmail = _db.Queryable<RedRushApplication>().Where(t => t.InstanceNumber == instanceNumber).First();
            if (toEmail != null)
            {
                email = toEmail.recipientEmail ?? email;
            }
            string content = string.Empty;
            var topic = "手工发票流程发票下载链接通知";
            var tplPath = Path.Combine(Directory.GetCurrentDirectory(), "EmailTemplate", "HandInvoiceUrlSendMail.cshtml");
            var template = File.ReadAllText(tplPath);
            var model = new { InstanceNumber = instanceNumber, SWSendMailSelected = list };
            content = Engine.Razor.RunCompile(template, template.GetHashCode().ToString(), null, model);
            if (!string.IsNullOrEmpty(content) && !string.IsNullOrEmpty(email))
            {
                _capBus.PublishAsync("bpmnew.EmailAppService.SendEmailAsync",
                  new Dto.SendEmailSimpleDto()
                  {
                      To = email,
                      Subject = topic,
                      Body = content
                  });
            }
        }

        private async Task<SearchPytResultDto> _searchTicketFromESB(string electricInvoiceCodes)
        {
            List<WhereCondition> listCondition = new List<WhereCondition>();
            DateTime dt = DateTime.Now;
            int year = dt.Date.Year;
            int month = dt.Date.Month;
            int dayCount = DateTime.DaysInMonth(year, month);
            string beginDate = new DateTime(year, month, 1).ToString("yyyyMMdd");
            string endDate = new DateTime(year, month, dayCount).ToString("yyyyMMdd");

            // 开票日期 ps: 日期范围查询时间段不超过 125天 不能跨年 时间段不超过125天，不允许跨年
            if (!string.IsNullOrEmpty(beginDate) && !string.IsNullOrEmpty(endDate))
            {
                listCondition.Add(new WhereCondition()
                {
                    field = "dateIssued",
                    values = new List<string> { beginDate, endDate },
                    conditionOP = "range",
                    value = ""
                });
            }

            // 电子发票代码
            if (!string.IsNullOrEmpty(electricInvoiceCodes))
            {

                var codes = electricInvoiceCodes.Split(new char[] { ',', ';', '，', '；', '|' }, StringSplitOptions.RemoveEmptyEntries);
                if (codes.Length == 1)
                {
                    listCondition.Add(new WhereCondition()
                    {
                        field = "invoiceNo",
                        value = electricInvoiceCodes,
                        conditionOP = "eq",
                        values = new List<string>()
                    });
                }
                else
                {
                    listCondition.Add(new WhereCondition()
                    {
                        field = "invoiceNo",
                        value = "",
                        conditionOP = "in",
                        values = codes.ToList()
                    });
                }
            }

            listCondition.Add(new WhereCondition()
            {
                field = "taxInvoiceSource",
                values = new List<string>(),
                conditionOP = "eq",
                value = "qd"
            });


            var sendPTYData = new SearchPTYDTO()
            {
                conditions = listCondition,
                page = new PYTPage()
                {
                    pageNo = 1,
                    pageSize = 100
                },
                sorts = new List<Sort>()
                {
                    new Sort()
                    {
                        field = "dateIssued",
                        value = "desc"
                    }
                }
            };

            var headers = new Dictionary<string, string>
            {
                {"sourceSystem", "BPMNEW"},
                {"serviceName", "S_XXX_SWGL_QueryBatchInvocieInfo_S "}
            };


            var searchResult = await _httpClient.ESBPostAsync<SearchPytResultDto>(_pytUrl, sendPTYData, headers);

            return searchResult;
        }

        private SAPVenderCodeResult Request(Guid redRushManualInvoice_Id, string order, string KPRQ, string InvoiceNo)
        {
            var dbModel = _db.Queryable<RedRushApplication, RedRushManualInvoice, RedRushManualInvoiceCostCenter>(
                                (app, rmi, rc) => new object[]{
                            JoinType.Inner, app.Id == rmi.RedRushApplication_Id,
                            JoinType.Left,rmi.Id== rc.RedRushManualInvoice_Id

                            }).Where((app, rmi, rc) => rmi.Id == redRushManualInvoice_Id && rmi.Order == order)
                            .Select((app, rmi, rc) => new Voice_CostCenter
                            {
                                RedRushApplication = app,
                                RedRushManualInvoice = rmi,
                                RedRushManualInvoiceCostCenter = rc
                            })
                            .ToList();
            var data = GetSAPVenderCode_2(dbModel, DateTime.ParseExact(KPRQ, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture).ToString("yyyy-MM-dd"), InvoiceNo);
            var result = PostSapVender(Newtonsoft.Json.JsonConvert.SerializeObject(data));
            return result;
        }

        private List<SAPVenderCode_2_3Model> GetSAPVenderCode_2(List<Voice_CostCenter> voice_CostCenters, string dateCertificateNo, string invoiceNO)
        {
            var voice_CostCentersFirst = voice_CostCenters.First();
            var userAccount = "BPMSGFP2";
            var orderIndex = voice_CostCentersFirst.RedRushManualInvoice.Order;
            var companyCode = voice_CostCentersFirst.RedRushApplication.InvoiceCompanyCode;
            string instanceId = string.Empty;
            var instanceInfo = _dbEngine.Queryable<Instances>().Where(x => x.Number == voice_CostCentersFirst.RedRushManualInvoice.InstanceNumber).First();
            if (instanceInfo != null)
            {
                instanceId = instanceInfo.InstanceId.ToString();
            }
            else
            {
                instanceId = "T" + _dbEngine.Queryable<HandInvoiceThird>().Where(x => x.InstanceNumber == voice_CostCentersFirst.RedRushManualInvoice.InstanceNumber).First().Id.ToString();
            }

            #region 增加判断条件
            var channel = voice_CostCentersFirst.RedRushApplication.Channel;
            var channelName = voice_CostCentersFirst.RedRushApplication.ChannelName;
            var applicationContentName = voice_CostCentersFirst.RedRushManualInvoice.ApplicationContentName;
            #endregion

            SAPVenderCode_2_3Model result = new SAPVenderCode_2_3Model()
            {
                BusinessId = voice_CostCentersFirst.RedRushManualInvoice.Id.ToString(),
                FlowInstId = voice_CostCentersFirst.RedRushManualInvoice.InstanceNumber,
                OperatorNumber = userAccount,
                PostHead = new PostHead()
                {
                    CompanyCode = companyCode,
                    VoucherPostingDate = dateCertificateNo,
                    VoucherTitleText = "手工发票",
                    ReferenceVoucherNumber = invoiceNO,
                    OrderNumber = instanceId + voice_CostCentersFirst.RedRushManualInvoice.Order.PadLeft(2, '0'),
                },
                PostItems = new List<PostItems>()
            };
            //如果是电票的话 发票号码放在文本里，摘要为空
            if (invoiceNO.Length > 10)
            {
                result.PostHead.VoucherTitleText = invoiceNO;
                result.PostHead.ReferenceVoucherNumber = "";
            }
            var defaultCompanyList = "1000,1100,1200,1800,9N00,9E00,5H00,5I00";
            var companylist = _SHOUGONGFAPIAOCOMPANY;
            if (!string.IsNullOrWhiteSpace(companylist))
            {
                defaultCompanyList = companylist;
            }
            var SapSubjectCode = "5102030002";
            var SapSubjectName = "营业收入-服务（非主营）";
            var flag = defaultCompanyList.ToLower().Split(new char[] { ',', '，', ';', ';' }, StringSplitOptions.RemoveEmptyEntries).Any(t => t.Trim() == companyCode.Trim().ToLower());

            if (flag)
            {
                //SapSubjectCode = "5101010302";
                //SapSubjectName = "营业收入-服务";

                #region 增加成本账逻辑
                if (channelName.Trim() == "99-关联企业")
                {
                    SapSubjectCode = "5401010608";
                    SapSubjectName = "营业成本-关联劳务";
                }
                if (channelName.Trim() == "98-其他")
                {
                    SapSubjectCode = "5401010404";
                    SapSubjectName = "营业成本-服务(非关联)";
                }
                if (channelName.Trim() != "99-关联企业")
                {
                    SapSubjectCode = "5401010404";
                    SapSubjectName = "营业成本-服务(非关联)";
                }
                #endregion

            }

            #region 非1000,1100,1200,1800,9N00,9E00,5H00,5I00这些公司时
            if (!flag)
            {
                //IU手工发票  
                //SapSubjectCode = "5101010302";
                //SapSubjectName = "营业收入-服务";
                if (channelName.Trim() == "99-关联企业")
                {
                    SapSubjectCode = "5405060000";
                    SapSubjectName = "其业务业成本-关联劳务";
                }
                if (channelName.Trim() == "98-其他")
                {
                    SapSubjectCode = "5405070000";
                    SapSubjectName = "其他营业成本-服务(非关联)";
                }
                if (channelName.Trim() != "99-关联企业")
                {
                    if (companyCode.Trim().ToLower() == "9m00")
                    {
                        SapSubjectCode = "5401010698";
                        SapSubjectName = "营业成本-商品销售成本";
                    }
                    else
                    {
                        SapSubjectCode = "5405070000";
                        SapSubjectName = "其他营业成本-服务(非关联)";
                    }
                }
            }
            #endregion

            #region 租赁业务 
            //古岁玉：by add 2022年3月28日21:27:07 确认
            string[] applicationContentNames = { "租赁费（车辆等有形动产）", "房屋租赁费(9%)", "托盘租赁", "房屋租赁费(5%)", "房屋租赁费(6%)", "房屋租赁费", "车辆租赁费(不含司机)", "有形动产租赁(栈板等)", "车辆租赁费(含司机)" };

            var applicationContentNameFlag = applicationContentNames.Any(t => t.Trim() == applicationContentName);
            if (applicationContentNameFlag)
            {
                SapSubjectCode = "5405080000";
                SapSubjectName = "其他业务成本-租赁收入";
            }
            #endregion

            var postItems = voice_CostCenters.OrderBy(t => t.RedRushManualInvoiceCostCenter.Order).Select(t => new
            {
                b = new PostItems()
                {
                    RowSymbol = (t.RedRushManualInvoiceCostCenter.Order).ToString().PadLeft(3, '0'),
                    PostingKey = ((int)VenderTypeEnum.JIE).ToString(),
                    DCIndicator = EnumExtension.GetDescription(typeof(VenderTypeEnum), (int)VenderTypeEnum.JIE),
                    SapSubjectCode = SapSubjectCode,
                    SapSubjectName = SapSubjectName,
                    CustomerNumber = "",
                    AccountNumberOfVendorOrCreditor = "",
                    CostCenter = "",//t.RedRushManualInvoiceCostCenter.CostCenterCode,
                    ProfitCenter = t.RedRushManualInvoiceCostCenter.ProfitCenter,//利润中心
                                                                                 //AmountInDocumentCurrency = t.RedRushManualInvoiceCostCenter.TotalAmount ?? 0,
                    AmountInDocumentCurrency = Math.Truncate((t.RedRushManualInvoiceCostCenter.TotalAmount ?? 0) * 100) / 100,
                    //AmountInLocalCurrency = t.RedRushManualInvoiceCostCenter.TotalAmount ?? 0,
                    AmountInLocalCurrency = Math.Truncate((t.RedRushManualInvoiceCostCenter.TotalAmount ?? 0) * 100) / 100,
                    AssignmentNumber = "HBPM-" + t.RedRushManualInvoice.InstanceNumber + "-" + t.RedRushManualInvoiceCostCenter.Order,//.ToString().PadLeft(3, '0'),
                    ItemText = $"成本结转-{t.RedRushManualInvoice.InvoiceContent}",
                    BaselineDateForDueDateCalculation = dateCertificateNo,
                    CreditControlArea = "",
                    BusinessPartnerReferenceKey1 = "",
                    BusinessPartnerReferenceKey2 = "",
                    ReferenceKeyForLineItem = "",
                    ItemCcc = (t.RedRushManualInvoiceCostCenter.Order).ToString().PadLeft(3, '0'),
                    SubjectCode = SapSubjectCode,
                    SubjectName = SapSubjectName,
                },
                a =
                new PostItems()
                {
                    RowSymbol = (t.RedRushManualInvoiceCostCenter.Order).ToString().PadLeft(3, '0'),
                    PostingKey = ((int)VenderTypeEnum.DAI_2).ToString(),
                    DCIndicator = EnumExtension.GetDescription(typeof(VenderTypeEnum), (int)VenderTypeEnum.DAI_2),
                    SapSubjectCode = t.RedRushManualInvoiceCostCenter.SubjectCode,
                    SapSubjectName = t.RedRushManualInvoiceCostCenter.Subject,
                    CustomerNumber = "",
                    AccountNumberOfVendorOrCreditor = "",
                    CostCenter = t.RedRushManualInvoiceCostCenter.CostCenterCode,
                    ProfitCenter = t.RedRushManualInvoiceCostCenter.ProfitCenter,//利润中心
                                                                                 //AmountInDocumentCurrency = (t.RedRushManualInvoiceCostCenter.TotalAmount ?? 0) * -1,
                    AmountInDocumentCurrency = Math.Truncate((t.RedRushManualInvoiceCostCenter.TotalAmount ?? 0) * -1 * 100) / 100,
                    //AmountInLocalCurrency = (t.RedRushManualInvoiceCostCenter.TotalAmount ?? 0) * -1,
                    AmountInLocalCurrency = Math.Truncate((t.RedRushManualInvoiceCostCenter.TotalAmount ?? 0) * -1 * 100) / 100,
                    AssignmentNumber = "HBPM-" + t.RedRushManualInvoice.InstanceNumber + "-" + t.RedRushManualInvoiceCostCenter.Order,//.ToString().PadLeft(3, '0'),
                    ItemText = $"成本结转-{t.RedRushManualInvoice.InvoiceContent}",
                    BaselineDateForDueDateCalculation = dateCertificateNo,
                    CreditControlArea = "",
                    BusinessPartnerReferenceKey1 = "",
                    BusinessPartnerReferenceKey2 = "",
                    ReferenceKeyForLineItem = "",
                    ItemCcc = (t.RedRushManualInvoiceCostCenter.Order).ToString().PadLeft(3, '0'),
                    SubjectCode = t.RedRushManualInvoiceCostCenter.SubjectCode,
                    SubjectName = t.RedRushManualInvoiceCostCenter.Subject,
                }
            }).OrderBy(t => t.a.RowSymbol).ThenBy(t => t.a.AssignmentNumber).ToList();

            var _postItems = new List<PostItems>();
            var count = 1;

            foreach (var item in postItems)
            {
                item.b.RowSymbol = count.ToString().PadLeft(3, '0');
                _postItems.Add(item.b);
                count = count + 1;
                item.a.RowSymbol = count.ToString().PadLeft(3, '0');
                _postItems.Add(item.a);
                count = count + 1;
            }

            result.PostItems = _postItems.OrderBy(t => t.ItemCcc).ThenBy(t => t.PostingKey).ToList();

            //插入主凭证

            var resultList = new List<SAPVenderCode_2_3Model>();
            resultList.Add(result);
            return resultList;
        }

        private SAPVenderCodeResult PostSapVender(string str)
        {
            var errormessage = string.Empty;
            var SAPVenderCodeResult = new SAPVenderCodeResult();
            try
            {
                var model = Newtonsoft.Json.JsonConvert.DeserializeObject<List<SAPVenderCode_2_3Model>>(str);
                if (model != null)
                {
                    //调用SAP 获取凭证
                    //SAPVenderCodeResult = PostT<List<SAPVenderCode_2_3Model>, SAPVenderCodeResult>(model, _FINANCEAPIURL).Result;
                    SAPVenderCodeResult = FinanceTaxAccountingAsync(Newtonsoft.Json.JsonConvert.SerializeObject(model)).Result;
                    var businessids = Guid.Parse(model[0].BusinessId);
                    var RushManualInvoiceList = _db.Queryable<RedRushManualInvoice>().First(t => t.Id == businessids);

                    if (RushManualInvoiceList != null)
                    {
                        var venderType = model[0].OperatorNumber;
                        var venderFlag = false;
                        if (SAPVenderCodeResult.Code != 0)
                        {
                            if (venderType.Contains("2"))
                            {
                                RushManualInvoiceList.SAPVenderCode2 = "未生成-1";
                            }
                            else
                            {
                                RushManualInvoiceList.SAPVenderCode3 = "未生成-1";
                            }
                            _db.Updateable<RedRushManualInvoice>(RushManualInvoiceList).ExecuteCommand();
                            return SAPVenderCodeResult;
                        }

                        if (SAPVenderCodeResult.Result[0].Status == "0" || SAPVenderCodeResult.Result[0].Status == "3")
                        {
                            venderFlag = true;
                        }

                        if (venderType.Contains("2"))
                        {
                            RushManualInvoiceList.SAPVenderCode2 = venderFlag ? SAPVenderCodeResult.Result[0].VoucherNo : SAPVenderCodeResult.Result[0].Message;
                            var redRushManualInvoiceCostCenter = _db.Queryable<RedRushManualInvoiceCostCenter>().Where(t => t.RedRushManualInvoice_Id == businessids).ToList();
                            if (!redRushManualInvoiceCostCenter.Any())
                            {
                                RushManualInvoiceList.SAPVenderCode2 = "无成本账";
                            }
                        }
                        else
                        {
                            //增加判断逻辑,IU手工发票不生成3号凭证
                            var rs = _db.Queryable<RedRushApplication>().Where(p => p.InstanceNumber == RushManualInvoiceList.InstanceNumber && p.ApplicationType == 2).ToList();
                            if (!rs.Any())
                            {
                                RushManualInvoiceList.SAPVenderCode3 = venderFlag ? SAPVenderCodeResult.Result[0].VoucherNo : SAPVenderCodeResult.Result[0].Message;
                            }
                        }
                        _db.Updateable<RedRushManualInvoice>(RushManualInvoiceList).ExecuteCommand();
                    }
                }
            }
            catch (Exception ex)
            {
                errormessage = ex.Message;
            }
            return SAPVenderCodeResult;
        }

        public async Task<outT> PostT<inT, outT>(inT T, string url, Dictionary<string, string> header = null)
        {
            var outTResult = default(outT);
            using (var httpClient = new HttpClient())
            {
                if (header != null)
                {
                    header.Add("requestId", System.Guid.NewGuid().ToString());
                    header.Add("trackId", System.Guid.NewGuid().ToString("N"));
                    foreach (var item in header)
                    {
                        httpClient.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                var result = await httpClient.PostAsJsonAsync(url, T);
                if (result.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var str = result.Content.ReadAsStringAsync().Result;

                    if (!string.IsNullOrEmpty(str))
                    {
                        outTResult = Newtonsoft.Json.JsonConvert.DeserializeObject<outT>(str);
                    }
                }
            }
            return outTResult;
        }

        /// <summary>
        /// 财务管税同记过账
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<SAPVenderCodeResult> FinanceTaxAccountingAsync(string input)
        {
            var tokenDto = await GetFinanceToken();
            var tokenString = $"{tokenDto.token_type} {tokenDto.access_token}";
            var headers = new Dictionary<string, string>
            {
                {"sourceSystem", "BPMNEW"},
                {"serviceName", "S_XXX_Finance_TaxAccounting_S"},
                {"Authorization", tokenString}
            };

            var rst = await _httpClient.ESBPostAsync<SAPVenderCodeResult>(_esbFinanceHeaderApi, input, headers);
            return rst;
        }


        /// <summary>
        /// 获取财务管理平台Token
        /// </summary>
        /// <returns></returns>
        public async Task<GetFinanceTokenOutput> GetFinanceToken()
        {
            var headers = new Dictionary<string, string>
            {
                {"sourceSystem", "BPMNEW"},
                {"serviceName", "S_XXX_Finance_GetToken_S"}
            };

            var input = new
            {
                client_id = "bpm",
                client_secret = "secret",
                grant_type = "client_credentials"
            };

            var rst = await _httpClient.ESBPostAsync<GetFinanceTokenOutput>(_esbFinanceTokenApi, input, headers);
            return rst;
        }
    }

    public class Voice_CostCenter
    {
        public RedRushManualInvoice RedRushManualInvoice { get; set; }
        public RedRushManualInvoiceCostCenter RedRushManualInvoiceCostCenter { get; set; }
        public RedRushApplication RedRushApplication { get; set; }
    }

    public class SAPVenderCode_2_3Model : ServiceBaseModel
    {
        /// <summary>
        /// 过账人工号
        /// </summary>
        public string OperatorNumber { get; set; }

        public PostHead PostHead { get; set; }

        public List<PostItems> PostItems { get; set; }

    }

    public class ServiceBaseModel
    {
        public string FlowInstId { get; set; }

        public string BusinessId { get; set; }

    }

    public class PostHead
    {
        /// <summary>
        /// 公司编码
        /// 发票所属公司
        /// </summary>
        public string CompanyCode { get; set; }
        /// <summary>
        /// 凭证类型
        /// 固定
        /// </summary>
        public string VoucherType { get { return "BX"; } }
        /// <summary>
        /// 凭证过账日期
        /// 18凭证返回日期
        /// </summary>
        public string VoucherPostingDate { get; set; }
        /// <summary>
        /// 凭证抬头文本
        /// </summary>
        public string VoucherTitleText { get; set; }
        /// <summary>
        /// 货币码
        /// </summary>
        public string CurrencyKey { get { return "CNY"; } }
        /// <summary>
        /// 参考凭证号(单据号+年度)
        /// 物理发票号
        /// </summary>
        public string ReferenceVoucherNumber { get; set; }
        /// <summary>
        /// 单据号（费控这边为10位数字单据号，不能和费控这边单据号重复规则各个调用方系统可以自己定义）
        /// BPM流程号
        /// </summary>
        public string OrderNumber { get; set; }
        /// <summary>
        /// 单据类型
        /// </summary>
        public string OrderType { get { return "59"; } }
        /// <summary>
        /// 36位GUID（一个单据多凭证场景、无此场景可不必传）绑定事务使用
        /// </summary>
        public string GUID { get { return Guid.NewGuid().ToString(); } }

    }

    public class PostItems
    {
        /// <summary>
        /// 凭证行项目标识
        /// </summary>
        public string RowSymbol { get; set; }
        /// <summary>
        /// 记帐代码
        /// </summary>
        public string PostingKey { get; set; }
        /// <summary>
        /// 借方/贷方标识
        /// </summary>
        public string DCIndicator { get; set; }
        /// <summary>
        /// 总帐帐目
        /// </summary>
        public string SapSubjectCode { get; set; }
        /// <summary>
        /// 总帐帐目名称
        /// </summary>
        public string SapSubjectName { get; set; }
        /// <summary>
        /// 客户编号
        /// </summary>
        public string CustomerNumber { get; set; }
        /// <summary>
        /// 供应商或债权人的帐号
        /// </summary>
        public string AccountNumberOfVendorOrCreditor { get; set; }
        /// <summary>
        /// 成本中心
        /// </summary>
        public string CostCenter { get; set; }
        /// <summary>
        /// 利润中心
        /// </summary>
        public string ProfitCenter { get; set; }
        /// <summary>
        /// 凭证货币金额
        /// </summary>
        public decimal AmountInDocumentCurrency { get; set; }
        /// <summary>
        /// 本位币计金额
        /// </summary>
        public decimal AmountInLocalCurrency { get; set; }
        /// <summary>
        /// 分配编号
        /// </summary>
        public string AssignmentNumber { get; set; }
        /// <summary>
        /// 项目文本
        /// </summary>
        public string ItemText { get; set; }
        /// <summary>
        /// 用于到期日计算的基准日期
        /// </summary>
        public string BaselineDateForDueDateCalculation { get; set; }
        /// <summary>
        /// 贷方控制范围
        /// </summary>
        public string CreditControlArea { get; set; }
        /// <summary>
        /// 业务伙伴参考码1
        /// </summary>
        public string BusinessPartnerReferenceKey1 { get; set; }
        /// <summary>
        /// 业务伙伴参考码1
        /// </summary>
        public string BusinessPartnerReferenceKey2 { get; set; }
        /// <summary>
        /// 业务伙伴参考码1
        /// </summary>
        public string ReferenceKeyForLineItem { get; set; }
        /// <summary>
        /// 单据行项目标识
        /// </summary>
        public string ItemCcc { get; set; }
        /// <summary>
        /// 明细科目
        /// </summary>
        public string SubjectCode { get; set; }
        /// <summary>
        /// 明细科目名称
        /// </summary>
        public string SubjectName { get; set; }

    }

    public enum VenderTypeEnum
    {
        [Description("S")]
        JIE = 40,
        [Description("H")]
        DAI_2 = 50,
        [Description("H")]
        DAI_3 = 34
    }

    public class SAPVenderCodeResult
    {
        public List<VenderResult> Result { get; set; }
        /// <summary>
        /// 接口返回状态码，0成功,其他失败
        /// </summary>
        public int Code { get; set; }
        public string Message { get; set; }
    }


    public class VenderResult
    {
        /// <summary>
        /// 过账状态:
        ///0:过账成功 1:过账失败2:过账异常 3:重复过账
        /// </summary>
        public string Status { get; set; }
        /// <summary>
        /// 单据号
        /// </summary>
        public string OrderNumber { get; set; }
        /// <summary>
        /// 单据类型(默认：59)
        /// </summary>
        public string OrderType { get; set; }
        /// <summary>
        /// 单据类型名称
        /// </summary>
        public string OrderTypeName { get; set; }
        /// <summary>
        /// 凭证号，Status不为0时，此字段为空
        /// </summary>
        public string VoucherNo { get; set; }
        /// <summary>
        /// 公司编码，Status不为0时，此字段为空
        /// </summary>
        public string CompanyCode { get; set; }
        /// <summary>
        /// 年度，Status不为0时，此字段为0000
        /// </summary>
        public string Year { get; set; }
        /// <summary>
        /// 返回此单据过账失败的信息
        /// </summary>
        public string Message { get; set; }
        /// <summary>
        /// GUID，过账时传入的GUID，若未传则为空
        /// </summary>
        public string GUID { get; set; }
    }
}